<script setup lang="ts">
import { ref, computed, toRefs } from 'vue'

import { useStore } from 'vuex'
import { IUserInfo } from '../models/IUserInfo';
// import useState  from '../store/useState'

//storeCurrent这里是对默认导出的组件取的别名
import storeCurrent from '../store/index'

defineProps<{ msg: string }>()

const count = ref(0)

//#region 使用store

//1. 利用 useStore 来使用store对象
const store = useStore()


//使用三种方式来测试获取userName，发现 userInfo.userName是响应式的
let userInfo: IUserInfo = store.state.user
//为响应式数据
console.log("使用useStore来调用store对象：" + userInfo.nickname)

//计算属性是响应式
let userName = computed(() => {
  return store.getters.getUserName
})

//重新赋值给getter属性，不是响应式了，getter不是响应式很正常
userName = store.getters.getUserName


const isAdminByGetter = storeCurrent.getters.isAdmin()


//2. 使用导出的对象直接使用store对象，都是可以的
let newUser: IUserInfo = storeCurrent.state.user

console.log("直接使用store对象来调用store对象：" + newUser.nickname)

//#endregion


//#region 使用mutation的发布的方法来改变 state中的值
/**
 * 使用 mutation来改变 vuex中的值,有一种脱裤子放屁的感觉
 */
const setAdmin = () => {
  console.log("设置管理员..")
  store.commit("setUserInfo", {
    id: 1
  })

  console.log("更改后用户的id为:", store.state)
  console.log(store.getters.isAdmin())
}


//直接使用isAdmin不是响应式的，需要使用computed来处理成响应式的
// 计算属性其实就是Ref类型，而Ref其实就是通过ES2022的proxy的getter/setter来实现的
// 可以发现，每次更新了userInfo.id,计算属性都会自动调用一次

let dyIsAdmin = computed(() => {
  console.log("调用computed计算是否为admin..")
  return store.getters.isAdmin(userInfo.id)
})

//#endregion

//#region  在vue3中如何将store中的state属性进行mapState操作，只能通过二次封装实现 
/**
 * 通过mapState 将 state中的属性都变成响应式
 * 在Vue3中，这玩意儿竟然用不了了，破烂玩意儿
 * 
 * 1、新建useMapper.js
 * 2、新建useState.js
 * 3、新建useGetters.js
 * 4、新建useActions.js
 * 5、页面中使用
 * 
 * 
 * 这样写是不对的
 */
// let mapComputed=computed(
//     // ...mapState({'option',["id","account"]})
// )

//可以这样，一个个获取,非常麻烦
// const idByComputed = computed(() => store.state.user.id);
// const nicknameByComputed = computed(() => store.state.user.nickname);


/**
 * 使用action 来更改内容
 */
const triggerActions = () => {
  store.dispatch('updateNickname', { nickname: '张三' });
}

//要使用...mapState的功能，在Vue3中是没有办法直接用的
//只能封装：答案是封装mapState，mapGetters，mapActions方法。
// const storeState = useState('home', ['id','account', 'nickname', 'status'])


//直接通过toRefs解构state中的对象到相应的变量中,保持响应式
const { id } = toRefs(store.state);

//直接通过toRefs解构getters中的对象到相应的变量中,保持响应式，注意：isAdmin解构出来仍然是一个方法
//使用时是 isAdmin(id:number)
const { getUserName, isAdmin:getIsAdmin, getUserNameFun } = toRefs(store.getters)
</script>

<template>

  <h1>通过state对象获取的信息：{{ userInfo.nickname }}</h1>
  <h1>通过getter属性获取的： {{ userName }}</h1>
  <h5>通过toRefs解构出来的对像，看是否是响应式的:{{ getUserName }}</h5>
  <h5>通过toRefs解构出来的对像，getUserNameFun看是否是响应式的:{{ getUserNameFun() }}</h5>

  <button type="button" @click="triggerActions" class="primary">更改名称</button>



  <h2>获取mapState中的值:{{ id }}</h2>

  <h4>当前用户是否为管理员：{{ isAdminByGetter ? '是管理员' : '不是管理员' }}</h4>
  <h4>通过解构getters来获取是否为管理员:{{ getIsAdmin() ? '是管理员' : '不是管理员' }}</h4>

  <h4>使用 getter解构出来的对象  直接获取为响应式数据</h4>
  <h4>当前用户是否为管理员：{{ dyIsAdmin ? '是管理员' : '不是管理员' }}</h4>
  <h5>通过toRefs解构出来的对像，看是否是响应式的:{{ getIsAdmin(count) }}</h5>


  <button type="button" @click="setAdmin" class="primary">设置为管理员</button>

  <h1>{{ msg }}</h1>

  <div class="card">
    <button type="button" @click="count++">count is {{ count }}</button>
    <p>
      Edit
      <code>components/HelloWorld.vue</code> to test HMR
    </p>
  </div>

  <p>
    Check out
    <a href="https://vuejs.org/guide/quick-start.html#local" target="_blank">create-vue</a>, the official Vue + Vite
    starter
  </p>
  <p>
    Install
    <a href="https://github.com/vuejs/language-tools" target="_blank">Volar</a>
    in your IDE for a better DX
  </p>
  <p class="read-the-docs">Click on the Vite and Vue logos to learn more</p>
</template>

<style scoped>
.read-the-docs {
  color: #888;
}
</style>